package com.brush.brushcommon.utils;

import lombok.extern.log4j.Log4j2;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
@Log4j2(topic = "business")
public class HttpClientUtil {
    public static String requestByGetMethod(String uri, Boolean jsonp){
        String result = "";

        //创建默认的httpClient实例
        CloseableHttpClient httpClient = getHttpClient();
        try {
            //用get方法发送http请求
            HttpGet get = new HttpGet(uri);
            System.out.println("执行get请求:...."+get.getURI());
            CloseableHttpResponse httpResponse = null;
            //发送get请求
            httpResponse = httpClient.execute(get);
            try{
                //response实体
                HttpEntity entity = httpResponse.getEntity();
                if (null != entity){
                    String json = EntityUtils.toString(entity);
                    System.out.println("响应状态码:"+ httpResponse.getStatusLine());
                    System.out.println("-------------------------------------------------");
                    System.out.println("响应内容:" + json);
                    System.out.println("-------------------------------------------------");

                    result = jsonp==true ? fmtJson(json) : json;
                    System.out.println("格式化json：" + result);
                }
            }
            finally{
                httpResponse.close();
            }
        } catch (Exception e) {
            log.error("catch Exception",e);
        }
        finally{
            try{
                closeHttpClient(httpClient);
            } catch (IOException e){
                log.error("catch Exception",e);
            }
        }
        return result;
    }



    public static String requestByPostMethod(String uri, List<NameValuePair> list, boolean jsonp) throws Exception{
        String result = "";
        CloseableHttpClient httpClient = getHttpClient();
        try {
            HttpPost post = new HttpPost(uri);          //这里用上本机的某个工程做测试
            //url格式编码
            UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(list,"UTF-8");
            post.setEntity(uefEntity);
            System.out.println("POST 请求...." + post.getURI());
            //执行请求
            CloseableHttpResponse httpResponse = httpClient.execute(post);
            try{
                HttpEntity entity = httpResponse.getEntity();
                if (null != entity){
                    String json = EntityUtils.toString(entity);
                    System.out.println("响应状态码:"+ httpResponse.getStatusLine());
                    System.out.println("-------------------------------------------------");
                    System.out.println("响应内容:" + json);
                    System.out.println("-------------------------------------------------");

                    result = jsonp==true ? fmtJson(json) : json;
                    System.out.println("格式化json：" + result);
                }
            } finally{
                httpResponse.close();
            }

        } catch( UnsupportedEncodingException e){
            log.error("catch Exception",e);
        }
        catch (IOException e) {
            log.error("catch Exception",e);
        }
        finally{
            try{
                closeHttpClient(httpClient);
            } catch(Exception e){
                log.error("catch Exception",e);
            }
        }
        return result;
    }

    private static CloseableHttpClient getHttpClient(){
        return HttpClients.createDefault();
    }

    private static void closeHttpClient(CloseableHttpClient client) throws IOException{
        if (client != null){
            client.close();
        }
    }

    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param param 请求参数。
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String param, URLConnection conn) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常！" + e);
            log.error("catch Exception",e);
        }
        //使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                log.error("catch Exception",ex);
            }
        }
        return result;
    }

    private static String fmtJson(String str) {
        int fristIndex = str.indexOf("{");
        //为什么会去掉最后一个字符 不清楚  如果改动会有影响
        return str.substring(fristIndex,str.length()-1);
    }

    /**
     * 调用对方接口方法
     * @param path 对方或第三方提供的路径
     * @param data 向对方或第三方发送的数据，大多数情况下给对方发送JSON数据让对方解析
     * @param 	"Content-Type", "application/json; charset=utf-8"
     */
    public static String httpPost(String path,String data) {
        String restr="";
        try {
            URL url = new URL(path);
            //打开和url之间的连接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            PrintWriter out = null;
            //请求方式
            conn.setRequestMethod("POST");
//           //设置通用的请求属性
            conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
            //设置是否向httpUrlConnection输出，设置是否从httpUrlConnection读入，此外发送post请求必须设置这两个
            //最常用的Http请求无非是get和post，get请求可以获取静态页面，也可以把参数放在URL字串后面，传递给servlet，
            //post与get的 不同之处在于post的参数不是放在URL字串里面，而是放在http请求的正文内。
            conn.setDoOutput(true);
            conn.setDoInput(true);
            //获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            //发送请求参数即数据
            out.print(data);
            //缓冲数据
            out.flush();
            //获取URLConnection对象对应的输入流
            InputStream is = conn.getInputStream();
            //构造一个字符流缓存
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String str = "";
            while ((str = br.readLine()) != null) {
                System.out.println("打印的结果是："+"\n"+str);
                restr+=str;
            }
            //关闭流
            is.close();
            //断开连接，最好写上，disconnect是在底层tcp socket链接空闲时才切断。如果正在被其他线程使用就不切断。
            //固定多线程的话，如果不disconnect，链接会增多，直到收发不出信息。写上disconnect后正常一些。
            conn.disconnect();
            System.out.println("完整结束");
        } catch (Exception e) {
            log.error("catch Exception",e);
        }
        return restr;
    }

}
